/**
 * 本地存储工具类
 * 提供统一的本地存储接口，支持 localStorage 和 sessionStorage
 */

export type StorageType = 'local' | 'session'

export interface StorageOptions {
  type?: StorageType
  prefix?: string
  expire?: number // 过期时间（毫秒）
}

interface StorageItem<T = any> {
  value: T
  expire?: number
  timestamp: number
}

class StorageManager {
  private prefix: string
  private storage: Storage

  constructor(options: StorageOptions = {}) {
    this.prefix = options.prefix || 'reactim_'
    this.storage = options.type === 'session' ? window.sessionStorage : window.localStorage
  }

  /**
   * 生成存储键名
   */
  private getKey(key: string): string {
    return `${this.prefix}${key}`
  }

  /**
   * 检查项目是否过期
   */
  private isExpired(item: StorageItem): boolean {
    if (!item.expire) return false
    return Date.now() > item.timestamp + item.expire
  }

  /**
   * 设置存储项
   */
  set<T>(key: string, value: T, expire?: number): boolean {
    try {
      const item: StorageItem<T> = {
        value,
        expire,
        timestamp: Date.now()
      }
      this.storage.setItem(this.getKey(key), JSON.stringify(item))
      return true
    } catch (error) {
      console.error('Storage set error:', error)
      return false
    }
  }

  /**
   * 获取存储项
   */
  get<T>(key: string): T | null {
    try {
      const itemStr = this.storage.getItem(this.getKey(key))
      if (!itemStr) return null

      const item: StorageItem<T> = JSON.parse(itemStr)
      
      // 检查是否过期
      if (this.isExpired(item)) {
        this.remove(key)
        return null
      }

      return item.value
    } catch (error) {
      console.error('Storage get error:', error)
      return null
    }
  }

  /**
   * 移除存储项
   */
  remove(key: string): boolean {
    try {
      this.storage.removeItem(this.getKey(key))
      return true
    } catch (error) {
      console.error('Storage remove error:', error)
      return false
    }
  }

  /**
   * 清空所有带前缀的存储项
   */
  clear(): boolean {
    try {
      const keys = Object.keys(this.storage).filter(key => 
        key.startsWith(this.prefix)
      )
      keys.forEach(key => this.storage.removeItem(key))
      return true
    } catch (error) {
      console.error('Storage clear error:', error)
      return false
    }
  }

  /**
   * 检查存储项是否存在
   */
  has(key: string): boolean {
    return this.get(key) !== null
  }

  /**
   * 获取所有键名
   */
  keys(): string[] {
    try {
      return Object.keys(this.storage)
        .filter(key => key.startsWith(this.prefix))
        .map(key => key.replace(this.prefix, ''))
    } catch (error) {
      console.error('Storage keys error:', error)
      return []
    }
  }

  /**
   * 获取存储大小（字节）
   */
  size(): number {
    try {
      let size = 0
      Object.keys(this.storage).forEach(key => {
        if (key.startsWith(this.prefix)) {
          size += (this.storage.getItem(key) || '').length
        }
      })
      return size
    } catch (error) {
      console.error('Storage size error:', error)
      return 0
    }
  }

  /**
   * 清理过期项
   */
  cleanup(): number {
    let cleanedCount = 0
    try {
      const keys = this.keys()
      keys.forEach(key => {
        const item = this.get(key)
        if (item === null) {
          cleanedCount++
        }
      })
    } catch (error) {
      console.error('Storage cleanup error:', error)
    }
    return cleanedCount
  }
}

// 创建默认实例
export const localStorage = new StorageManager({ type: 'local' })
export const sessionStorage = new StorageManager({ type: 'session' })

// 用户相关存储
export const userStorage = {
  // 用户信息
  setUserInfo: (userInfo: any) => localStorage.set('user_info', userInfo),
  getUserInfo: () => localStorage.get('user_info'),
  removeUserInfo: () => localStorage.remove('user_info'),

  // 认证令牌
  setToken: (token: string, expire?: number) => localStorage.set('auth_token', token, expire),
  getToken: () => localStorage.get<string>('auth_token'),
  removeToken: () => localStorage.remove('auth_token'),

  // 刷新令牌
  setRefreshToken: (token: string, expire?: number) => localStorage.set('refresh_token', token, expire),
  getRefreshToken: () => localStorage.get<string>('refresh_token'),
  removeRefreshToken: () => localStorage.remove('refresh_token'),

  // 清除所有用户数据
  clearUserData: () => {
    localStorage.remove('user_info')
    localStorage.remove('auth_token')
    localStorage.remove('refresh_token')
  }
}

// 聊天相关存储
export const chatStorage = {
  // 草稿消息
  setDraft: (conversationId: string, draft: string) => 
    sessionStorage.set(`draft_${conversationId}`, draft),
  getDraft: (conversationId: string) => 
    sessionStorage.get<string>(`draft_${conversationId}`) || '',
  removeDraft: (conversationId: string) => 
    sessionStorage.remove(`draft_${conversationId}`),

  // 聊天设置
  setChatSettings: (settings: any) => localStorage.set('chat_settings', settings),
  getChatSettings: () => localStorage.get('chat_settings'),

  // 最后访问的会话
  setLastConversation: (conversationId: string) => 
    localStorage.set('last_conversation', conversationId),
  getLastConversation: () => localStorage.get<string>('last_conversation'),

  // 消息缓存
  setCachedMessages: (conversationId: string, messages: any[], expire?: number) => 
    localStorage.set(`messages_${conversationId}`, messages, expire || 24 * 60 * 60 * 1000), // 24小时过期
  getCachedMessages: (conversationId: string) => 
    localStorage.get<any[]>(`messages_${conversationId}`) || [],
  removeCachedMessages: (conversationId: string) => 
    localStorage.remove(`messages_${conversationId}`),

  // 分页状态缓存
  setPaginationState: (conversationId: string, state: any) => 
    sessionStorage.set(`pagination_${conversationId}`, state),
  getPaginationState: (conversationId: string) => 
    sessionStorage.get(`pagination_${conversationId}`),
  removePaginationState: (conversationId: string) => 
    sessionStorage.remove(`pagination_${conversationId}`),

  // 消息加载失败记录
  setLoadFailure: (conversationId: string, failure: any) => 
    sessionStorage.set(`load_failure_${conversationId}`, failure, 5 * 60 * 1000), // 5分钟过期
  getLoadFailure: (conversationId: string) => 
    sessionStorage.get(`load_failure_${conversationId}`),
  removeLoadFailure: (conversationId: string) => 
    sessionStorage.remove(`load_failure_${conversationId}`),

  // 清理会话相关缓存
  clearConversationCache: (conversationId: string) => {
    chatStorage.removeCachedMessages(conversationId)
    chatStorage.removePaginationState(conversationId)
    chatStorage.removeLoadFailure(conversationId)
    chatStorage.removeDraft(conversationId)
  },

  // 离线消息缓存
  addOfflineMessage: (message: { id: string; data: any; timestamp: Date }) => {
    const offlineMessages = chatStorage.getOfflineMessages()
    offlineMessages.push(message)
    localStorage.set('offline_messages', offlineMessages)
  },
  getOfflineMessages: () => 
    localStorage.get<Array<{ id: string; data: any; timestamp: Date }>>('offline_messages') || [],
  removeOfflineMessage: (messageId: string) => {
    const offlineMessages = chatStorage.getOfflineMessages()
    const filteredMessages = offlineMessages.filter(msg => msg.id !== messageId)
    localStorage.set('offline_messages', filteredMessages)
  },
  clearOfflineMessages: () => localStorage.remove('offline_messages'),

  // 清理所有消息缓存
  clearAllMessageCache: () => {
    const keys = localStorage.keys()
    keys.forEach(key => {
      if (key.startsWith('messages_') || key.startsWith('pagination_') || key.startsWith('load_failure_')) {
        localStorage.remove(key)
      }
    })
  }
}

// 应用设置存储
export const appStorage = {
  // 主题设置
  setTheme: (theme: string) => localStorage.set('app_theme', theme),
  getTheme: () => localStorage.get<string>('app_theme') || 'light',

  // 语言设置
  setLanguage: (language: string) => localStorage.set('app_language', language),
  getLanguage: () => localStorage.get<string>('app_language') || 'zh-CN',

  // 通知设置
  setNotificationSettings: (settings: any) => localStorage.set('notification_settings', settings),
  getNotificationSettings: () => localStorage.get('notification_settings'),

  // 应用版本
  setAppVersion: (version: string) => localStorage.set('app_version', version),
  getAppVersion: () => localStorage.get<string>('app_version'),
}

export default StorageManager